package com.rwy.web.filter.authorize;

import java.io.Closeable;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.function.Predicate;

import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpStatus;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.rwy.util.ObjectUtil;
import com.rwy.util.RWYException;
import com.rwy.util.StringUtil;
import com.rwy.util.WebUtil;
import com.rwy.util.constant.AppTokenEnum;

import lombok.extern.log4j.Log4j;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

@Log4j
public class UserAuthorizeInterceptor extends HandlerInterceptorAdapter {
	private String redicect_url; // 微信用户登录回调链接
	private String login_fault_redirect_url;//fault login url
	private String js_sdk_ticket_url;
	private static String openid_key = AppTokenEnum.common_app_token.getToken_key();
    private CacheManager cacherManager;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if (request.getRequestURI().contains(redicect_url)
				|| request.getRequestURI().contains(login_fault_redirect_url)) {
			return true;
		}

		if (DispatcherType.ERROR.equals(request.getDispatcherType())) {
			//faileResponse(response, request, " bad request ", HttpStatus.SC_BAD_REQUEST);
			return true;
		}
		log.info(request.getParameter(openid_key));
		log.info(getUser(request.getParameter(openid_key)));
		Predicate<String> openIDpred = (a) -> (StringUtil.isEmpty(request.getParameter(a)) || ObjectUtil.isEmpty(getUser(request.getParameter(a))));
		// 暂时不做用户信息过期
		
		if (openIDpred.test(openid_key)) {
			faileResponse(response, request, " request unauthorized ", HttpStatus.SC_UNAUTHORIZED);
			return false;
		}
		return true;
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		try {
			int status = 400;
		if (!ObjectUtil.isEmpty(ex)) {
			AuthorizeStatus json = new AuthorizeStatus();
			if (ex instanceof RWYException.AuthorizeException) {
				json.setErrorCode(""+HttpStatus.SC_UNAUTHORIZED);
				json.setMsg("Unauthorized Request !");
				status = HttpStatus.SC_UNAUTHORIZED;
			} else if (ex instanceof RWYException.ErrorException) {
				json.setErrorCode("000405");
				json.setMsg("request error !");
				status = HttpStatus.SC_BAD_REQUEST;
			} else if(ex instanceof RWYException.UnAuthorizeException) {
				json.setErrorCode("00000");
				json.setMsg("without business partner role .. ");
				status = HttpStatus.SC_UNAUTHORIZED;
			}else if(ex instanceof RWYException.NoMobileAuthorizeException) {
				json.setErrorCode("00001");
				json.setMsg("Must fill the mobile in WeiXin !");
				status = HttpStatus.SC_UNAUTHORIZED;
			}
			else {
				json.setErrorCode("000500");
				json.setMsg("request error, plase contact us ! ");
				status = HttpStatus.SC_INTERNAL_SERVER_ERROR;
			}
			log.error(ex.getMessage());
			faileResponse(response, request, json, status);
			ex = null;
		}
		}catch(Exception e){
			log.error(e.getMessage());
		}
	}

	/**
	 * oAuth认证失败时的输出
	 * 
	 * @param res
	 * @throws OAuthSystemException
	 * @throws IOException
	 */
	private void faileResponse(HttpServletResponse res, HttpServletRequest req, String errorMsg, Integer status) throws Exception {
		res.setCharacterEncoding("UTF-8");
		res.setContentType("application/json; charset=utf-8");
		res.setStatus(status);
		PrintWriter writer = res.getWriter();
		writer.write(authorizeErrorMesage(status, req.getRequestURI()));
		writer.flush();
		writer.close();
		log.error("error:  error msg " + errorMsg);
		log.error(" error: user authorize mesage response data:" + authorizeErrorMesage(status, req.getRequestURI(), WebUtil.getParameters(req).toString()));

	}
	
	
	private void faileResponse(HttpServletResponse res, HttpServletRequest req, AuthorizeStatus json, Integer status) throws Exception {
		Gson gson = new GsonBuilder().create();
		res.reset();
		res.setCharacterEncoding("UTF-8");
		res.setContentType("application/json; charset=utf-8");
		res.setStatus(status);
		PrintWriter writer = res.getWriter();
		writer.write(gson.toJson(json));
		writer.flush();
		writer.close();
		log.error(" error: user authorize mesage response data:" + authorizeErrorMesage(status, req.getRequestURI(), WebUtil.getParameters(req).toString()));

	}
	
	private Element getUser(String openid) {
		if (StringUtil.isEmpty(openid)) return null;
		Element user = cacherManager.getCache("users").get(openid);
		return user;
	}

	public void close(Closeable c) {
		if (c == null)
			return;
		try {
			c.close();
		} catch (IOException e) {
			//
		}
	}

	private String authorizeErrorMesage(Integer code, String request) {
		AuthorizeStatus msg = new AuthorizeStatus(""+code, request);
		Gson gson = new GsonBuilder().create();
		return gson.toJson(msg);
	}
	private String authorizeErrorMesage(Integer code, String request, String msg) {
		AuthorizeStatus data = new AuthorizeStatus(""+code, request, msg);
		Gson gson = new GsonBuilder().create();
		return gson.toJson(data);
	}

	public String getRedicect_url() {
		return redicect_url;
	}

	public void setRedicect_url(String redicect_url) {
		this.redicect_url = redicect_url;
	}

	public CacheManager getCacherManager() {
		return cacherManager;
	}

	public void setCacherManager(CacheManager cacherManager) {
		this.cacherManager = cacherManager;
	}

	public String getLogin_fault_redirect_url() {
		return login_fault_redirect_url;
	}

	public void setLogin_fault_redirect_url(String login_fault_redirect_url) {
		this.login_fault_redirect_url = login_fault_redirect_url;
	}

	public String getJs_sdk_ticket_url() {
		return js_sdk_ticket_url;
	}

	public void setJs_sdk_ticket_url(String js_sdk_ticket_url) {
		this.js_sdk_ticket_url = js_sdk_ticket_url;
	}
	
	

}
